<template>
    <div class="sand-box" ref="sandbox">
        <div ref="textRef" v-show="false">
            <slot></slot>
        </div>
        <div class="s--show-template">
            <!-- <div id="comApp"></div> -->
            <div v-if="app" class="t--app">
                <component :is="app"></component>
            </div>
        </div>
        <div class="s--edit-template">
            <div class="e--content" :style="{height:height + 'px'}">
                <div class="c--edtiors" ref="editorsRef">
                    <els-codemirror class="e--codemirror" title="html template" mode="htmlmixed" v-model="template" @submit="rebuild"></els-codemirror>
                    <els-codemirror class="e--codemirror" title="vue options" mode="application/json" v-model="contextStr" @submit="rebuild"></els-codemirror>
                </div>
            </div>
            <div class="e--fire-switch" @click="status = !status">{{status?'上拉隐藏':'下拉显示'}}</div>
        </div>
    </div>
</template>

<script>
    export default {
        name:'sand-box',
        components:{
        },
        data:() => ({
            status:false,
            height:0,
            text:'',

            contextStr:'',
            template:'',
            app:undefined,
        }),
        computed:{
            context(){
                const c = this.contextStr;
                return eval("(" + c + ")");
            }
        },
        methods:{
            test(arg){
                return arg
            },
            initComponent(){
                const t = this.template
                const c = this.context;
                return {
                    template:t,
                    ...c
                }
            },
            initText(){
                this.text = this.$refs.textRef.textContent;
            },
            initTemplate(){
                const t = /<template>([\s\S]*)<\/template>/.exec(this.text)
                this.template = (t && t[1] || '').trim()
            },
            initContext(){
                const t = /<script>([\s\S]*)<\/script>/.exec(this.text)
                const c = ((t && t[1]) || '{}').replace(/>(\s*)</g,'><').replace(/[\r\n]*/g,'').trim()
                this.contextStr = c;
            },
            rebuild(){
                const c = this.initComponent();
                this.app = c;
            },
            utilJsonFormat(v){
                return v;
            },
            utilHtmlFormat(v){
                return v;
            }
        },
        mounted(){
            this.initText();
            this.initTemplate();
            this.initContext();
            this.rebuild();
        },
        watch:{
            status(){
                this.height = this.status?this.$refs.editorsRef.offsetHeight:0;
            }
        }
    }
</script>

<style scoped lang="scss">
    .sand-box{
        border:1px solid #ddd;
        border-radius:4px;
        color:#666;
        .s--show-template{
            padding:10px;
            border-bottom:1px solid #ddd;
            .t--app{
                overflow: hidden;
            }
        }
        .s--edit-template{
            .e--content{
                transition:height 0.5s;
                min-height:0;
                overflow: hidden;
                .c--edtiors{
                    padding:10px;
                    display:flex;
                    align-items: center;
                    .e--codemirror{
                        flex:1;
                        margin:0 10px;
                    }
                }
            }
            .e--fire-switch{
                position:sticky;
                bottom:0;
                font-weight: 500;
                color:#666;
                background:#fff;
                text-align: center;
                padding:8px;
                border-top:1px solid #ddd;
                // border-bottom:1px solid #ddd;
                border-bottom-left-radius: 4px;
                border-bottom-right-radius: 4px;
                z-index: 9999;
                cursor:pointer;
                &:hover{
                    background:#ecf5ff;
                    color:#409eff;
                }
            }
        }
    }
</style>
